package models;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

import models.deadbolt.RoleHolder;
import play.data.validation.Required;
import play.db.jpa.Model;
import play.mvc.Scope.Session;
import securesocial.provider.UserId;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Usuario extends Model implements RoleHolder {
	
	private static final long serialVersionUID = -9213531477486756233L;
	
	private String email;
	private String nombre;
	private String socialUserId;

	@OneToMany(mappedBy="autor", cascade=CascadeType.ALL)
	private List<Plato> platos;
	
	@Required
	@ManyToMany(cascade = CascadeType.ALL)
    public List<ADietaRol> roles = new ArrayList<ADietaRol>();
	
	public Usuario(String email, String password, String nombre, UserId socialUserId, List<ADietaRol> aDietaRoles) {
		this.email = email;
		this.nombre = nombre;
		this.socialUserId = socialUserId.id;
		this.roles.addAll(aDietaRoles);
	}
	
	@Override
	public List<ADietaRol> getRoles() {
		return roles;
	}
	
	public String getEmail() {
		return email;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}
	
	public String getNombre() {
		return nombre;
	}
	
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	
	public String getSocialUserId() {
		return socialUserId;
	}
	
	public void setSocialUserId(String socialUserId) {
	        this.socialUserId = socialUserId;
	}
	
	private Boolean tieneRol(TipoRol tipoRol) {
		for (ADietaRol rol : this.getRoles()) {
			if (rol.getRoleName().equals(tipoRol)) {
				return true;
			}
		}
		
		return false;
		
	}
	
	/**
	 * Agrega el paciente al listado y establece el estado del paciente en Pendiente
	 */
	public void agregarPlato(Plato plato) {
		getPlatos().add(plato);
//		plato.getAutor().add(arg0); // hay que ver qué relación tiene el autor con el plato para asignarle un autor directo o agregarlo a una lista
//		plato.setHabilitado(Boolean.FALSE); // hay que ver cómo vamos a habilitar el plato
	}
	
	public Boolean isAdmin() {
		return tieneRol(TipoRol.ADMIN);
	}
	
	public Boolean isNutri() {
		return tieneRol(TipoRol.NUTRI);
	}
	
	public Boolean isPaciente() {
		return tieneRol(TipoRol.PACIENTE);
	}

	public Boolean isEstablecimientoAlimenticio() {
		return tieneRol(TipoRol.ESTABLECIMIENTO_ALIMENTICIO);
	}
	
	public void addNutriToSession(Session session) {
		// no hago nada para EstablecomientoAlimenticio ni Admin
	}

	public Paciente getPacienteToCreateObjective(Long pacienteId) {
		// returno null para los usuarios que no tienen que ver con objetivos
		return null;
	}

	public List<Plato> getPlatos() {
		return platos;
	}

	public void setPlatos(List<Plato> platos) {
		this.platos = platos;
	}

}
